package com.credithc.signature.core.service;

import com.credithc.signature.common.mapper.CertMapper;
import com.credithc.signature.common.mapper.FddSealInfoMapper;
import com.credithc.signature.common.mapper.SealInfoMapper;
import com.credithc.signature.common.po.*;
import com.credithc.signature.common.ro.sign.SealCertInfoRo;
import com.credithc.signature.common.service.*;
import com.credithc.signature.common.to.CFCASignResult;
import com.credithc.signature.common.to.CFCASignTO;
import com.credithc.signature.common.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述：签章服务入口<br/>
 * 作者：sunyang
 * 创建：2019/6/5 16:41
 * 版本：v1.0.0<br/>
 */
@Slf4j
@Service
public class SignatureService {

    @Value("${signature.snapSignPdf.path}")
    String snapPDFPath;

    @Value("${signature.maxBatchSignNum:160}")
    Integer maxBatchSignNum;

    @Autowired
    TemplateService templateService;

    @Autowired
    CFCASignService cfcaSignService;

    @Autowired
    SealInfoService sealInfoService;

    @Autowired
    SignatureLogService signatureLogService;

    @Autowired
    OfficialSealTemplateService officialSealTemplateService;

    @Autowired
    CertMapper certMapper;

    @Autowired
    CertInfoService certInfoService;

    @Autowired
    ChannelService channelService;

    @Autowired
    FddSealInfoMapper fddSealInfoMapper;

    @Autowired
    SealInfoMapper sealInfoMapper;

    /**
     * 更新过期私章信息
     *
     * @param tempMakePersonSeal
     * @param cfcaSignTO
     * @param expireApplyInfo
     */
    public void updateExpirePersonalSeal(List<CFCASignTO> tempMakePersonSeal, CFCASignTO cfcaSignTO, SealApplyInfoDTO expireApplyInfo) {
        for (CFCASignTO tempSignTO : tempMakePersonSeal) {
            java.sql.Date current = new java.sql.Date(System.currentTimeMillis());
            SealApplyInfoDTO tempApplyInfo = new SealApplyInfoDTO(expireApplyInfo.getId(), tempSignTO.getSealCode(), tempSignTO.getSealPassword(),
                    tempSignTO.getUserName(), tempSignTO.getIdTypeCode(), tempSignTO.getUserIdNo(), current, current, current, current);
            certInfoService.updateByPrimaryKeySelective(tempApplyInfo);
            cfcaSignTO.setSealCode(tempSignTO.getSealCode());
            cfcaSignTO.setSealPassword(tempSignTO.getSealPassword());
        }
    }

    /**
     * 获取公章相关信息--中金
     *
     * @param requestSn
     * @param templateNo
     * @return
     * @throws Exception
     */
    public List<CFCASignTO> getOfficialSealInfoList(String requestSn, String templateNo, List<String> sealCodes) throws Exception {
        // 1、获取公章信息集合
        List<CFCASignTO> collect = new ArrayList<>();
        List<SealInfo> sealInfos = new ArrayList<>();
        List<String> sealCodeList = new ArrayList<>();
        if (sealCodes == null) {
            OfficialSealTemplate officialSealTemplate = new OfficialSealTemplate();
            officialSealTemplate.setTemplateNo(templateNo);
            List<OfficialSealTemplate> officialSealTemplates = officialSealTemplateService.selectByExample(officialSealTemplate);
            if (officialSealTemplates == null || officialSealTemplates.size() == 0) {
                log.error("消息:requestSn={},签章公章出现异常,该模板没有公章", requestSn);
                throw new Exception("模板没有公章");
            }
            sealCodeList = officialSealTemplates.stream().map(sealTemplate -> sealTemplate.getOfficialSealCode()).collect(Collectors.toList());
            sealInfos = sealInfoService.selectBySealCodeList(sealCodeList);
        } else if (sealCodes.isEmpty()) {
            sealInfos = new ArrayList<>();
        } else {
            sealInfos = sealInfoService.selectBySealCodeList(sealCodes);
        }

        // 2、检查公章状态
        for (SealInfo sealInfo : sealInfos) {
            if (StringUtils.isBlank(sealInfo.getKeyWords())) {
                log.error("－消息－:requestSn={},公章关键信息没有找到,请在系统配置管理中配置", requestSn);
                throw new RuntimeException("公章关键信息没有找到,请在系统配置管理中配置");
            }
            if (sealInfo.getStatus() == 0) {
                log.error("－消息－:requestSn={},公章状态不可用,请检查", requestSn);
                throw new RuntimeException("公章状态不可用,请检查;模板编号:" + templateNo);
            }

            CFCASignTO cfcaSignTO = generateCFCASignTO(requestSn, sealInfo);
            checkAndResumptionOfficialSealExpire(requestSn, sealInfo, cfcaSignTO);
            collect.add(cfcaSignTO);
        }
        return collect;
    }

    /**
     * 获取公章相关信息--法大大
     *
     * @param requestSn
     * @param templateNo
     * @return
     * @throws Exception
     */
    public List<CFCASignTO> getOfficalSealInfoList2(String requestSn, String templateNo, List<String> sealCodes) throws Exception {
        List<CFCASignTO> collect = new ArrayList<>();
        List<FddSealInfo> sealInfos = new ArrayList<>();
        List<String> sealCodeList = new ArrayList<>();
        if (sealCodes == null) {
            OfficialSealTemplate officialSealTemplate = new OfficialSealTemplate();
            officialSealTemplate.setTemplateNo(templateNo);
            List<OfficialSealTemplate> officialSealTemplates = officialSealTemplateService.selectByExample(officialSealTemplate);
            if (officialSealTemplates == null || officialSealTemplates.size() == 0) {
                log.error("－消息－:requestSn={},签章公章出现异常,该模板没有公章", requestSn);
                throw new Exception("模板没有公章");
            }
            sealCodeList = officialSealTemplates.stream().map(sealTemplate -> sealTemplate.getOfficialSealCode()).collect(Collectors.toList());
            sealInfos = fddSealInfoMapper.selectBySealCodeList(sealCodeList);
        } else if (sealCodes.isEmpty()) {
            sealInfos = new ArrayList<>();
        } else {
            sealInfos = fddSealInfoMapper.selectBySealCodeList(sealCodes);
        }

        for (FddSealInfo fddSealInfo : sealInfos) {
            if (StringUtils.isBlank(fddSealInfo.getKeyWords())) {
                log.error("－消息－:requestSn={},公章关键信息没有找到,请在系统配置管理中配置", requestSn);
                throw new RuntimeException("公章关键信息没有找到,请在系统配置管理中配置");
            }
            if (fddSealInfo.getStatus() == 0) {
                log.error("－消息－:requestSn={},公章状态不可用,请检查", requestSn);
                throw new RuntimeException("公章状态不可用,请检查");
            }
            SealInfo sealInfo = new SealInfo();
            BeanUtils.copyProperties(fddSealInfo, sealInfo);
            CFCASignTO cfcaSignTO = generateCFCASignTO(requestSn, sealInfo);
            collect.add(cfcaSignTO);
        }
        return collect;
    }

    /**
     * 拼装CFCASignTO
     *
     * @param requestSn
     * @param sealInfo
     * @return
     * @throws Exception
     */
    private CFCASignTO generateCFCASignTO(String requestSn, SealInfo sealInfo) throws Exception {
        CFCASignTO cfcaSignTO = new CFCASignTO();
        cfcaSignTO.setKeyWord(sealInfo.getKeyWords());
        cfcaSignTO.setSealPassword(sealInfo.getSealPwd());
        cfcaSignTO.setSealName(sealInfo.getSealName());
        cfcaSignTO.setSealPerson(sealInfo.getSealPerson());
        cfcaSignTO.setUserName(sealInfo.getSealPerson());
        cfcaSignTO.setIdTypeCode(sealInfo.getIdentificationType());
        cfcaSignTO.setUserIdNo(sealInfo.getIdentificationNo());
        cfcaSignTO.setOrganCode(sealInfo.getSealOrg());
        cfcaSignTO.setSealImage(sealInfo.getImage());
        if (StringUtils.isBlank(sealInfo.getSealCode())) {
            log.error("－消息－:requestSn={},公章不存在", requestSn);
            throw new Exception("公章不存在");
        }
        cfcaSignTO.setSealCode(sealInfo.getSealCode());
        return cfcaSignTO;
    }

    /**
     * 校验公章是否过期，若过期重新生成
     *
     * @param requestSn
     * @param sealInfo
     * @param cfcaSealInfoTO
     * @throws Exception
     */
    private void checkAndResumptionOfficialSealExpire(String requestSn, SealInfo sealInfo, CFCASignTO cfcaSealInfoTO) throws Exception {
        SealCertInfoRo sealCertInfo = cfcaSignService.querySealInfo(requestSn, sealInfo.getSealCode());
        String certNotAfter = sealCertInfo.getCertNotAfter();
        int i = certNotAfter.compareTo(DateUtil.getStandardDateTimeStr());
        if (i < 0) {
            // 执行更新操作
            updateOfficeSeal(requestSn, cfcaSealInfoTO);

            Cert cert = new Cert();
            cert.setCertDn(sealCertInfo.getCertDN());
            cert.setCertSn(sealCertInfo.getCertSN());
            cert.setApplyTime(DateUtil.getDateFromStr2(sealCertInfo.getCertNotBefore()));
            cert.setExpireTime(DateUtil.getDateFromStr2(sealCertInfo.getCertNotAfter()));
            cert.setUpdateTime(DateUtil.getDateFromStr2(sealCertInfo.getCertNotBefore()));
            cert.setId(Long.valueOf(sealInfo.getCertId()));
            certMapper.updateByPrimaryKeySelective(cert);

            sealInfo.setUpdateTime(new Date());
            Example example = new Example(SealInfo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("sealCode", sealInfo.getSealCode());
            sealInfoMapper.updateByExampleSelective(sealInfo, example);
        }
    }

    /**
     * 更新过期公章信息
     *
     * @param requestSn
     * @param cfcaSealInfoTO
     * @return
     * @throws Exception
     */
    private void updateOfficeSeal(String requestSn, CFCASignTO cfcaSealInfoTO) throws Exception {
        CFCASignResult cfcaSignResult = cfcaSignService.updateOfficeSeal(cfcaSealInfoTO, requestSn);
        log.error("－消息－:requestSn={},公章更新结果:{}", requestSn, cfcaSignResult.getResultMsg());
        if (!cfcaSignResult.getIsSuccess()) {
            signatureLogService.updateResult(cfcaSignResult.getResultMsg(), requestSn);
            throw new RuntimeException("调用接口更新公章失败......" + cfcaSignResult.getResultMsg());
        }
    }

}
